package com.system.core.pay.util;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.util.Assert;

import com.system.core.pay.wechat.dto.WechatClientReq;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;

@UtilityClass
@Slf4j
public class WechatUtils {
	
	private CloseableHttpClient httpClient;
	
	public void getWechatPlatformCert(WechatClientReq req) throws Exception {
		String api = "https://api.mch.weixin.qq.com/v3/certificates";
		getClient(req);
	}

	public CloseableHttpClient getClient(WechatClientReq req) throws Exception {

		if(httpClient != null) {
			if(StringUtils.isNotBlank(req.getPrivateKey()) 
					|| StringUtils.isNotBlank(req.getSerialNumber())
					|| StringUtils.isNotBlank(req.getMerchantId())
					|| StringUtils.isNotBlank(req.getApiV3Key())) {
				log.warn("使用已有实例，入参无效！");
			}
			return httpClient;
		}
		try (var privateKeyStream = new ByteArrayInputStream(req.getPrivateKey().getBytes("utf-8"))){
			// 加载商户私钥（privateKey：私钥字符串）
			PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(privateKeyStream);
			
			if(req.isAutoUpdate()) {
				// 加载平台证书（mchId：商户号,mchSerialNo：商户证书序列号,apiV3Key：V3密钥）
				CertificatesManager certificatesManager = CertificatesManager.getInstance();
				var signer = new PrivateKeySigner(req.getSerialNumber(), merchantPrivateKey);
				var credentials = new WechatPay2Credentials(req.getMerchantId(), signer);
				certificatesManager.putMerchant(req.getMerchantId(),credentials,req.getApiV3Key().getBytes("utf-8"));
				
				// 初始化httpClient
				var verifier = certificatesManager.getVerifier(req.getMerchantId());
				var validator = new WechatPay2Validator(verifier);
				httpClient = WechatPayHttpClientBuilder.create()
						.withMerchant(req.getMerchantId(), req.getSerialNumber(), merchantPrivateKey)
						.withValidator(validator).build();
				return httpClient;
			} else {
				Assert.notEmpty(req.getMerchantPublicCert(), "必传平台公钥证书，可通过https://api.mch.weixin.qq.com/v3/certificates获取");
				var wechatPayCertificates = new ArrayList<X509Certificate>();
				for(String certPath:req.getMerchantPublicCert()) {
					try(var item = new FileInputStream(certPath)){
						wechatPayCertificates.add(PemUtil.loadCertificate(item));
					}
				}
				httpClient = WechatPayHttpClientBuilder.create()
						.withMerchant(req.getMerchantId(), req.getSerialNumber(), merchantPrivateKey)
						.withWechatPay(wechatPayCertificates).build();
				return httpClient;
			}
		} catch (Exception e) {
			throw e;
		}
	}
}
